<?php
require_once('AdroitBaseDB.class.php');

/**
 * AdroitDB class encapsulates common db actions into easier to use functions.
 *
 * @package adroit
 * @subpackage db
 */
class AdroitDB extends AdroitBaseDB {
	
    /**
     * AdroitBaseDB object
     */
    public static $dbase; 
    
    /**
     * Instantiates new AdroitBaseDB object and sets it as a static object $dbase
     *
     * @param Array $c Configuration parameters
     */
    public static function connect($c) {
        try {
            AdroitDB::$dbase = new AdroitBaseDB($c['name'], $c['server'], $c['user'], $c['password'], $c['port']);
        }catch(AdroitDBException $e) {
            throw new AdroitDBConnectionException("Error connecting to database");
        }
    }
    
	/**
	 * Saves an object to the table passed in
	 *
	 * @param String $tableName
	 * @param BaseDom $dom
	 * @param String $primaryKey
	 */
	public static function saveDom($tableName, $dom, $primaryKey) {
	    $domToArray = Array();
	    foreach($dom AS $key => $value) {
	        if($key != $primaryKey) {
	            $domToArray[$key] = $value;
	        }
	    }
	    $dom->id = AdroitDB::insertRecord($tableName, $domToArray, $primaryKey);
	}
	
	/**
	 * Updates an object in the table passed in
	 *
	 * @param String $tableName
	 * @param BaseDom $dom
	 * @param String $primaryKey
	 */
	public static function updateDom($tableName, $dom, $primaryKey) {
	    $domToArray = Array();
	    foreach($dom AS $key => $value) {
	        $domToArray[$key] = $value;
	    }
	    AdroitDB::updateRecord($tableName, $primaryKey, $dom->$primaryKey, $domToArray);
	}
	
	/**
	 * Returns a row of values in the table that matches the field/value passed in
	 *
	 * @param String $tableName
	 * @param String $value
	 * @param String $field
	 * @return Array
	 */
	public static function getDomByField($tableName, $value, $field) {
	    return AdroitDB::fetchRecord($tableName, $field, $value);
	}
	
	/**
	 * Inserts a new record into the table
	 *
	 * @param String $table_name
	 * @param Array $info_array
	 * @param String $primary_key
	 * @return Integer
	 */
	public static function insertRecord($table_name, $info_array, $primary_key='') {
	   if(isset($info_array[$primary_key])) {
	      unset($info_array[$primary_key]);
	   }
	   $info_array = AdroitDB::emptyBadFields($table_name, $info_array);
	   if(count($info_array) > 0) {
	      $query = "INSERT INTO `" . $table_name . "` ";
	      $query_set = "";
	      foreach($info_array as $field_name => $field_value) {
	         if($query_set == "") {
	            $query_set .= "SET ";
	         } else {
	            $query_set .= ", ";
	         }
	         if($field_value == null) {
	             $query_set .=  "`" . $field_name . "` = null ";
	         }else {
			     if($field_value === true || $field_value === false 
				 	|| $field_value === 'true' || $field_value === 'false') {
			     	$value = $field_value === true || $field_value === 'true' ? 1 : 0;
			     }else {
					$value = $field_value;
			     }
	             $query_set .=  "`" . $field_name . "` = '" . $value . "' ";
	         }
	      }
	      AdroitDB::$dbase->query($query.$query_set);
	      $insert_id = AdroitDB::$dbase->getInsertId();
	      return $insert_id;
	   } else {
	      die("Error: Bad Info passed to insertRecord function.");
	   }
	}
 
	/**
	 * Updates the record in the table passed in that matches the record_id
	 *
	 * @param String $table_name
	 * @param String $primary_key
	 * @param Integer $record_id
	 * @param Array $info_array
	 * @return boolean
	 */
	public static function updateRecord($table_name, $primary_key, $record_id, $info_array) {
	   if(isset($info_array[$primary_key])) {
	      unset($info_array[$primary_key]);
	   }
	   $info_array = AdroitDB::emptyBadFields($table_name, $info_array);
	   if(count($info_array) > 0) {
	      $query = "UPDATE `" . $table_name . "` ";
	      $query_set = "";
	      $query_whr = " WHERE `" . $primary_key . "`='" . $record_id . "'";
	      foreach($info_array as $field_name => $field_value) {
	         if($query_set == "") {
	            $query_set .= "SET ";
	         } else {
	            $query_set .= ", ";
	         }
	         if($field_value == null) {
	             $query_set .=  "`" . $field_name . "` = null ";
	         }else {
			     if($field_value === true || $field_value === false 
				 	|| $field_value === 'true' || $field_value === 'false') {
			     	$value = $field_value === true || $field_value === 'true' ? 1 : 0;
			     }else {
			     	$value = $field_value;
			     }
	             $query_set .=  "`" . $field_name . "` = '" . $value . "' ";
	         }
	      }
	      AdroitDB::$dbase->query($query.$query_set.$query_whr);
	      return true;
	   } else {
	      die("Error: Bad Info passed to updateRecord function.");
	   }
	}
 
	/**
	 * Deletes a record from the table passed in that matches the record_id passed in
	 *
	 * @param String $table_name
	 * @param String $primary_key
	 * @param Integer $record_id
	 * @return boolean
	 */
	public static function deleteRecord($table_name, $primary_key, $record_id) {
	   $query = "DELETE FROM `" . $table_name . "` ";
	   $query_whr = "WHERE `" . $primary_key . "`='" . $record_id . "'";
	   AdroitDB::$dbase->query($query . $query_whr);
	   return true;
	}
 
	/**
	 * Deletes any records from the table passed in that match the values passed in the search_array
	 *
	 * @param String $table_name
	 * @param Array $search_array
	 * @return booealn
	 */
	public static function deleteRecords($table_name, $search_array) {
	   $query = "DELETE FROM `" . $table_name . "` ";
	   $query_whr = "WHERE ";
	   foreach($search_array as $search_name => $search_value) {
	      if($query_whr != "WHERE ") {
	         $query_whr .= " AND ";
	      }
	      $query_whr .= "`" . $search_name . "`='" . $search_value . "'";
	   }
	   AdroitDB::$dbase->query($query . $query_whr);
	   return true;
	}
 
	/**
	 * Retrieves a record from the table passed in that matches the record_id passed in
	 *
	 * @param String $table_name
	 * @param String $primary_key
	 * @param Integer $record_id
	 * @return Array
	 */
	public static function fetchRecord($table_name, $primary_key, $record_id) {
	   $query = "SELECT * FROM `" . $table_name . "` WHERE `" . $primary_key . "`='" . $record_id . "'";
	   $result = AdroitDB::$dbase->fetchAssocRow($query);
	   return $result;
	}
 
	/**
	 * Retrieves any records from the table passed in that match the values in search_arr, sorted by sort_arr
	 *
	 * @param String $table_name
	 * @param Array $search_arr
	 * @param Array $sort_arr
	 * @param Array $join_arr
	 * @return Array
	 */
	public static function fetchRecords($table_name, $search_arr = Array(), $sort_arr = Array(), $join_arr = Array()) {
	   $query = "SELECT * FROM `" . $table_name . "`";
	   $query_join = "";
	   $query_whr = "";
	   $query_srt = "";
	   foreach($join_arr as $join_table => $join_on) {
	      $query_join .= " LEFT JOIN `" . $join_table . "` ON " . $join_on . "";
	   }
	   foreach($search_arr as $search_field => $search_value) {
	      if($query_whr == "") {
	         $query_whr .= " WHERE ";
	      } else {
	         $query_whr .= " AND ";
	      }
	      $query_whr .= "" . (is_array($search_value)?$search_field . " " . $search_value['Operator'] . " '" . $search_value['Value'] . "'":$search_field . "='" . $search_value . "'");
	   }
	   foreach($sort_arr as $sort_field) {
	      if($query_srt == "") {
	         $query_srt .= " ORDER BY ";
	      } else {
	         $query_srt .= ", ";
	      }
	      $query_srt .= $sort_field;
	   }
	   $results = AdroitDB::$dbase->fetchAssocArray($query.$query_join.$query_whr.$query_srt);
	   return $results;
	}
	
	public static function tableExists($table) {
		$query = 'SELECT 1 FROM `' . strtolower($table) . '` LIMIT 0';
		try {
			$result = @AdroitDB::$dbase->fetchAssocArray($query);
			return true;
		}catch(Exception $e) {
			return false;
		}
	}
 
	/**
	 * Removes any un-matching fields from the array passed in that aren't in the table passed in
	 *
	 * @param String $table_name
	 * @param Array $info_array
	 * @return Array
	 */
	private static function emptyBadFields($table_name, $info_array) {
		$fields_array = AdroitDB::fetchTableFields($table_name);
		foreach($info_array as $key => $value) {
		   if(!in_array($key, $fields_array)) {
		      unset($info_array[$key]);
		   }
		}
		return $info_array;
	}
      
	/**
	 * Gets the column names of the table passed in
	 * 
	 * @param String $table_name
	 * @return Array
	 */
	public static function fetchTableFields($table_name) {
	   $query = "describe `" . $table_name . "`";
	   $tmp_array = AdroitDB::$dbase->fetchAssocArray($query);
	   $fields_array = Array();
	   foreach($tmp_array as $tmp_field) {
	      $fields_array[] = $tmp_field['Field'];
	   }
	   return $fields_array;
	}
}
?>